﻿namespace NTracker.Tests.Injection
{
    using NTracker.Injection;
    using NUnit.Framework;
    using Rhino.Mocks;
    using System;
    using System.Collections.Generic;
    using NTracker.Tests.Mock;

    [TestFixture]
    public class DefaultDependencyResolverTests
    {
        private MockRepository mockRepository;
        private IBaseCatalog mockCatalog;
        private DefaultDependencyResolver resolver;
        private Microsoft.VisualStudio.TestTools.UnitTesting.PrivateObject wrapper;

        [TestFixtureSetUp]
        public void SetUp()
        {
            mockRepository = new MockRepository();
            mockCatalog = mockRepository.DynamicMock<IBaseCatalog>();
            using (mockRepository.Record())
            {
                Expect.Call(mockCatalog.Dependencies).Return(new Dictionary<string, Type> 
                { 
                    { "string", typeof(string) }, 
                    { "int", typeof(int) },
                    { "test", typeof(Sample) }
                });
            }

            resolver = new DefaultDependencyResolver(null, mockCatalog);
            wrapper = new Microsoft.VisualStudio.TestTools.UnitTesting.PrivateObject(resolver);
        }

        [Test]
        public void ExtractTypeFromCatalog_WhenContractExist_ReturnType()
        {
            // Given
            Type actual;
            Type expected = typeof(Sample);

            // When
            actual = (Type)wrapper.Invoke("ExtractTypeFromCatalog", "test");

            // Then
            Assert.AreEqual(expected, actual);
        }

        [Test]
        public void ExtractTypeFromCatalog_WhenContractNotExist_ReturnType()
        {
            // Given
            Type actual;
            Type expected = typeof(object);

            // When
            actual = (Type)wrapper.Invoke("ExtractTypeFromCatalog", "fake");

            // Then
            Assert.AreEqual(expected, actual);
        }

        [Test]
        public void ResolveGeneric_WhenTypeExistWithOneMoreConstructor_ReturnInstance()
        {
            // Given
            Sample actual;

            // When
            actual = resolver.Resolve<Sample>("test");

            // Then
            Assert.IsNotNull(actual);
        }

        [Test]
        public void ResolveReflectionCaller_ReturnInstance()
        {
            // Given
            dynamic actual;

            // When
            actual = resolver.Resolve("test");

            // Then
            Assert.IsNotNull(actual);
        }
    }
}
